v-for
可以用陣列或是物件帶入,比較特別的是用物件帶入的話,是用屬性來做索引。
<h4>陣列與物件的迴圈</h4>
// 陣列的索引是一般我們熟知的 0 到 陣列長度
<ul>
<li v-for="(item, key) in arrayData">
{{ key }} - {{ item.name }} {{ item.age }} 歲
</li>
</ul>
// 物件的索引是由『屬性』來擔當
<ul>
<li v-for="(item,key) in objectData">
{{key}} - {{item.name}} {{item,age}} 歲
</li>
</ul>
data: {
arrayData: [{
name: '小明',
age: 16
}, {
name: '漂亮阿姨',
age: 24
}, {
name: '杰倫',
age: 20
}],
objectData: {
ming: {
name: '小明',
age: 16
},
auntie: {
name: '漂亮阿姨',
age: 24
},
jay: {
name: '杰倫',
age: 20
}
},
},
vue 在切換畫面是部分置換,如果有 textbox 這類的 DOM 元素就無法置換,因為替換 DOM 元素是是快速置換,所以這裡的 textbox 不會變動。
<h4>Key</h4>
<ul>
<li v-for="(item, key) in arrayData">
{{ key }} - {{ item.name }} {{ item.age }} 歲
<input type="text">
</li>
</ul>
<button class="btn btn-outline-primary">反轉陣列</button>
methods: {
reverseArray: function() {
this.arrayData.reverse()
console.log(this.arrayData)
},
}
那要避免這個問題可以用 key
,這個 key
很像我們人的 ID ,要用無重複的值來當 key
。
<h4>Key</h4>
<ul>
<li v-for="(item, key) in arrayData" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲
<input type="text">
</li>
</ul>
<button class="btn btn-outline-primary">反轉陣列</button>
methods: {
reverseArray: function() {
this.arrayData.reverse()
console.log(this.arrayData)
},
}
過濾也很常搭配 v-for
來使用,我們可以用 textbox 來過濾出我們要的資料。
<h4>Filter</h4>
<input type="text" class="form-control" v-model="filterText">
<ul>
<li v-for="(item, key) in filterArray" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>
methods: {
filterData: function() {
// 這邊會需要把 this 存到變數中,因為在 for 迴圈中 this 會被替換掉。
// 這邊的 this 是指可以取用 vue 裡的 data
let vm = this;
console.log(vm);
// filter() 會回傳一個陣列,其條件是 return 後方為 true 的物件,很適合用在搜尋符合條件的資料。
vm.filterArray = vm.arrayData.filter(function(item) {
// vm.filterText 是我們當下搜尋的值
// item.name 是每個 item 的名稱
// item.name.match(vm.filterText) 用每一筆去跟搜尋的值判斷是否相同,相同就會是 true
console.log(vm.filterText, item.name, item.name.match(vm.filterText))
return item.name.match(vm.filterText);
});
}
}
第一個狀況:直接修改陣列長度
在原本 JS 如果我們對陣列的長度改為 0 的話,這個陣列內容會被刪除,但是我們在 vue.js 是無法操作的。
<h4>不能運作的狀況</h4>
<button class="btn btn-outline-primary" @click="cantWork">無法運行</button>
<ul>
<li v-for="(item, key) in arrayData" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>
cantWork: function() {
this.arrayData.length = 0;
console.log(this.arrayData);
}
在 console 或是 devtool 裡可以看到陣列長度是 0,但畫面上並沒有消除。
第二個狀況:修改某索引裡的資料
如果想嘗試修改索引 0 的資料是無法成功的。
<h4>不能運作的狀況</h4>
<button class="btn btn-outline-primary" @click="cantWork">無法運行</button>
<ul>
<li v-for="(item, key) in arrayData" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>
cantWork: function() {
this.arrayData[0] = {
name: "帥哥",
age: 23,
};
console.log(this.arrayData);
}
由 console 和 devtoole 上值都有改變,但畫面上就是沒有變動,在這裏可以知道我們無法用索引的方式來修改資料。
那我們要修改的話我們必須使用 Vue.set()
。
使用時機:當我們要操作 vue data 但這份資料並沒有在裡面的時候使用,將資料寫入到 data,讓它可以重新的監控。
<h4>不能運作的狀況</h4>
<button class="btn btn-outline-primary" @click="cantWork">無法運行</button>
<ul>
<li v-for="(item, key) in arrayData" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>
cantWork: function() {
Vue.set(this.arrayData, 0, {
name: "帥哥",
age: 23,
})
}
假設我們想讓兩個 tr 為一個群組的話可以用 template
,template
是不會被打印出來的。
<h4>Template 的運用</h4>
<p>請將兩個 tr 一組使用 v-for</p>
<table class="table">
<template v-for="item in arrayData">
<tr>
<td>{{item.age}}</td>
</tr>
<tr>
<td>{{item.name}}</td>
</tr>
</template>
</table>
v-for
與 v-if
同時寫在一個元素時 v-for
會先執行再執行 v-if
,所以可以藉由 v-if
來對迴圈做些判斷。
<h4>v-for 與 v-if</h4>
<ul>
<li v-for="(item, key) in arrayData" v-if="item.age<20">
{{ key }} - {{ item.name }} {{ item.age }} 歲
</li>
</ul>